package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.apis.apuser.IUserClient;
import com.heima.apis.article.IArticleClient;
import com.heima.apis.wemedia.IWemediaClient;
import com.heima.comment.service.CommentService;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.dtos.CommentSaveDto1;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentLike;
import com.heima.model.comment.vos.CommentVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.utils.thread.AppThreadLocalUtils;
import io.lettuce.core.Consumer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lzq
 * @data 2023/5/16 15:02
 */
@Service
@Slf4j
public class CommentServiceImpl implements CommentService {
    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private IWemediaClient iWemediaClient;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IUserClient iUserClient;
    @Autowired
    private IArticleClient iArticleClient;
    /**
     * 保存文章评论
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveByContent(CommentSaveDto1 dto) {
        //1参数校验
        if (dto==null||dto.getArticleId()==null|| StringUtils.isBlank(dto.getContent())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2判断是否登录,进行评论
        ApUser user = AppThreadLocalUtils.getUser();
        if (user==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN,"请先登录,再来评论");
        }
          //判断文章是否可以评论
        Long articleId = dto.getArticleId();
        ResponseResult responseResult = iArticleClient.isComment(articleId);
        String string = JSON.toJSONString(responseResult.getData());
        ApArticleConfig apArticleConfig = JSON.parseObject(string, ApArticleConfig.class);
        if (!apArticleConfig.getIsComment()){
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH,"该文章评论功能关闭");
        }
        //3判断字符串长度是否大于140
        String content = dto.getContent();
        int length = content.length();
        if (length>140){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"评论过长,请不要超过140个字符");
        }
        //4做文本垃圾检测校验
        //调用自定义敏感词过滤entryId
        List<WmSensitive> sensitive =iWemediaClient .findAllSensitive();
        if (sensitive!=null&&sensitive.size()>0){
            //调用DFA算法
            boolean flag= handleSensitiveScan(content, sensitive);
            if (!flag){
                return ResponseResult.errorResult(AppHttpCodeEnum.MATERIASL_REFERENCE_FAIL);
            }
        }
        //调用阿里云文字校验
       //Boolean flag= handleTextScan(content);
        Boolean flag=true;
        if (!flag){
            return ResponseResult.errorResult(AppHttpCodeEnum.MATERIASL_REFERENCE_FAIL);
        }
        //获取当前用户名称
        Integer id = user.getId();
        ResponseResult result = iUserClient.getUser(id);
        //ApUser user1 = (ApUser) result.getData();
        //数据转换,强转可能会出现储物
        String jsonString = JSON.toJSONString(result.getData());
        ApUser apUser = JSON.parseObject(jsonString, ApUser.class);
        ApComment apComment = new ApComment();
        //属性赋值
        apComment.setAuthorId(user.getId());
        apComment.setAuthorName(apUser.getName());
        apComment.setContent(dto.getContent());
        apComment.setEntryId(dto.getArticleId());
        apComment.setCreatedTime(new Date());
        apComment.setReply(0);
        apComment.setFlag(0);
        apComment.setType(0);
        apComment.setLikes(0);
        mongoTemplate.save(apComment);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    //调用阿里云文字校验
    private Boolean handleTextScan(String content) {
        Boolean flag=true;
        try {
            Map map = greenTextScan.greeTextScan(content);
            if (map!=null){
                if(map.get("suggestion").equals("block")){
                    flag = false;
                }
                //不确定信息  需要人工审核
                if(map.get("suggestion").equals("review")){
                    flag = false;
                    //调用人工逻辑
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 自定义敏感词过滤，基于DFA算法实现
     * @param content
     * @param
     */
    private boolean handleSensitiveScan(String content,List <WmSensitive>sensitive) {
        //标记位：假设审核没问题
        boolean flag = true;

        //查询系统敏感词
        List<String> list = sensitive.stream().map(wmSensitive -> wmSensitive.getSensitives()).collect(Collectors.toList());
        //1. 初始化敏感词库
        SensitiveWordUtil.initMap(list);

        //2. 进行敏感词匹配
        Map<String, Integer> resMap = SensitiveWordUtil.matchWords(content);

        //结果处理
        if (!resMap.isEmpty()){
            flag = false;
            log.info("评论审核失败，包含敏感词："+resMap);
        }

        return flag;
    }

    /**
     * 评论点赞
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //1参数校验
        if (dto.getCommentId()==null||dto==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //判断是否登录
        ApUser user = AppThreadLocalUtils.getUser();
        if (user==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //2评论点赞
        //获取评论id,查询评论
        String commentId = dto.getCommentId();
        Query query = new Query(Criteria.where("id").is(commentId));
        ApComment apComment = mongoTemplate.findOne(query, ApComment.class);
        if (dto.getOperation()==0){
            //点赞操作,增加点赞数量
           apComment.setLikes(apComment.getLikes() + 1);
           mongoTemplate.save(apComment);
           //记录当前用户对于当前评论记录
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setCommentId(apComment.getId());
            apCommentLike.setAuthorId(user.getId());
            mongoTemplate.save(apCommentLike);
        }else {
            //取消赞操作
            int i = apComment.getLikes() - 1;
            i=i<1?0:i;
            apComment.setLikes(i);
            mongoTemplate.save(apComment);
            //删除对应的用户和评论关系
            Query likeQuery = new Query(Criteria.where("authorId").is(apComment.getAuthorId()).and("authorId").is(user.getId()));
            mongoTemplate.remove(likeQuery,ApCommentLike.class);
        }
        HashMap<String, Integer> map = new HashMap<>();
        map.put("likes",apComment.getLikes());
        return ResponseResult.okResult(map);
    }

    /**
     * 展示评论列表
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(CommentDto dto) {
        //1参数校验
        if (dto==null||dto.getArticleId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2登录校验
        ApUser user = AppThreadLocalUtils.getUser();
        if (user==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //3查询文章中的评论(根据文章id,创建时间精确查询,创建时间排序和分页)
        Query query = new Query(Criteria.where("entryId")
                .is(dto.getArticleId())
                .and("createdTime").lt(dto.getMinDate()));
        query.with(Sort.by(Sort.Direction.DESC,"createdTime")).limit(10);
        List<ApComment> apCommentList = mongoTemplate.find(query, ApComment.class);
        if (apCommentList==null||apCommentList.size()<0){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //4查询登陆人是否点赞某条评论
        //获取所有评论id
        List<String> idList = apCommentList.stream().map(ApComment::getId).collect(Collectors.toList());
        //查询当前用户评论点赞(获取的是当前用户点赞的评论)
        Query query1 = new Query(Criteria.where("commentId").in(idList)
                .and("authorId").is(user.getId()));
        List<ApCommentLike> apCommentLikes = mongoTemplate.find(query1, ApCommentLike.class);
        ArrayList<CommentVo> commentVos = new ArrayList<>();
        //遍历集合(当前评论的id和当前用户点赞的评论id相同,则将点赞高亮)
        for (ApComment apComment : apCommentList) {
            CommentVo commentVo = new CommentVo();
            //属性拷贝
            BeanUtils.copyProperties(apComment,commentVo);
            for (ApCommentLike apCommentLike : apCommentLikes) {
                //如果文章评论是被当前用户点赞,赋值高亮
                if (apComment.getId().equals(apCommentLike.getCommentId())){
                    commentVo.setOperation((short)0);
                    break;
                }
            }
            commentVos.add(commentVo);
        }
        return ResponseResult.okResult(commentVos);
    }
}
